package com.ll.utils;

import org.apache.commons.lang3.StringUtils;

import java.sql.Timestamp;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.TimeZone;

/**
 * 日期工具类 Created by yubin on 2015/12/16 16:45.
 */
public class DateUtil {
    private static SimpleDateFormat shortSdf = new SimpleDateFormat("yyyy-MM-dd");
    private static SimpleDateFormat longHourSdf = new SimpleDateFormat("yyyy-MM-dd HH");
    private static SimpleDateFormat longSdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");

    private static final TimeZone GMT_TIMEZONE = TimeZone.getTimeZone("GMT");

    // public static String format(Date date, DatePattern pattern) {
    // return DateFormatUtils.format(date, pattern.getValue());
    // }

    /**
     * 功能: 时间转换成当地时区字符串<br/>
     * 说明: <br/>
     *
     * @param date
     * @return String
     * @author yubin
     */
    public static String format(Date date, DatePattern pattern) {
        return date2String(date, pattern.getValue());
    }

    //转换成格林威治时间
    public static String transferDatetimeToGMT(String dateTime) {
        if (StringUtils.isBlank(dateTime)) {
            return null;
        }
        Date date;
        if (dateTime.indexOf(" ") != -1) {
            date = DateUtil.string2Date(dateTime, DatePattern.yyyyMMddHHmmssLine);
        } else {
            date = DateUtil.string2Date(dateTime, DatePattern.yyyyMMdd);
        }
        return DateUtil.formatGMT(date, DatePattern.yyyyMMddHHmmssLine);
    }

    /**
     * 时间转换成GMT时间
     *
     * @param date
     * @return date
     * @throws ParseException
     */
    public static Date dateFormatGMT(Date date) throws ParseException {
        String dateOld = formatGMT(date, DatePattern.yyyyMMddHHmmssLine);
        return string2DateGMT(dateOld, DatePattern.yyyyMMddHHmmssLine);
    }

    /**
     * 功能: 时间转换成GMT时区字符串<br/>
     * 说明: <br/>
     *
     * @param date
     * @return String
     * @author yubin
     */
    public static String formatGMT(Date date, DatePattern pattern) {
        return date2String(date, pattern.getValue(), GMT_TIMEZONE);
    }

    /**
     * 功能: 字符串转换成当地时间<br/>
     * 说明: <br/>
     *
     * @param date
     * @param pattern
     * @return Date
     * @author yubin
     */
    public static Date string2Date(String date, DatePattern pattern) {
        return string2Date(pattern.getValue(), date);
    }

    /**
     * 功能: 字符串转换成格林威治时间<br/>
     * 说明: <br/>
     *
     * @param date
     * @param pattern
     * @return Date
     * @throws ParseException
     * @author yubin
     */
    public static Date string2DateGMT(String date, DatePattern pattern) throws ParseException {
        SimpleDateFormat sdf = new SimpleDateFormat(pattern.getValue());
        sdf.setTimeZone(GMT_TIMEZONE);
        return sdf.parse(date);
    }

    /**
     * 获取第二天
     *
     * @param currentDayStr
     * @return
     * @throws ParseException
     */
    public static Date getNextDay(String currentDayStr) {
        Calendar c = Calendar.getInstance();
        try {
            c.setTime(longSdf.parse(currentDayStr));
        } catch (ParseException e) {
            //TODO
        }
        c.add(Calendar.DATE, 1);
        return c.getTime();

    }

    /**
     * 获取第二天(返回时间字符串)
     *
     * @param currentDayStr
     * @return
     * @throws ParseException
     */
    public static String getNextDayStr(String currentDayStr) {
    	if (StringUtils.isBlank(currentDayStr)) {
			return "";
		}
        return DateUtil.format(DateUtil.getNextDay(currentDayStr), DatePattern.yyyyMMdd);
    }

    /**
     * 功能: 获取当前时间<br/>
     * 说明: <br/>
     *
     * @return Date
     * @author yubin
     */
    public static Date getCurrentDate() {
        return new Date();
    }
    
    /**
     * 功能: 将时间戳转换为时间<br/>
     * 说明: <br/>
     * @param timeStamp 单位：毫秒
     *
     * @return Date
     * @author zhangxingbing
     */
    public static Date getDate(Long timeStamp){
         return new Date(timeStamp);   // 时间戳转换成时间
    }

//    /**
//     * 获得本周的第一天，周一
//     *
//     * @return
//     */
//    public static Date getCurrentWeekDayStartTime() {
//        Calendar c = Calendar.getInstance();
//        try {
//            int weekday = c.get(Calendar.DAY_OF_WEEK) - 2;
//            c.add(Calendar.DATE, -weekday);
//            c.setTime(longSdf.parse(shortSdf.format(c.getTime()) + " 00:00:00"));
//        } catch (Exception e) {
//            e.printStackTrace();
//        }
//        return c.getTime();
//    }

//    /**
//     * 获得本周的最后一天，周日
//     *
//     * @return
//     */
//    public static Date getCurrentWeekDayEndTime() {
//        Calendar c = Calendar.getInstance();
//        try {
//            int weekday = c.get(Calendar.DAY_OF_WEEK);
//            c.add(Calendar.DATE, 8 - weekday);
//            c.setTime(longSdf.parse(shortSdf.format(c.getTime()) + " 23:59:59"));
//        } catch (Exception e) {
//            e.printStackTrace();
//        }
//        return c.getTime();
//    }

    /**
     * 获得本天的开始时间，即2012-01-01 00:00:00
     *
     * @return
     */
    public static String getCurrentDayStartTime() {
        Date now = DateUtil.getCurrentDate();
        try {
            return transferDatetimeToGMT(format(now,DatePattern.yyyyMMdd)+" 00:00:00");
        } catch (Exception e) {
            e.printStackTrace();
            return "";
        }

    }

    /**
     * 获得本天的结束时间，即2012-01-01 23:59:59
     *
     * @return
     */
    public static String getCurrentDayEndTime() {
        Date now = DateUtil.getCurrentDate();
        try {
            return  transferDatetimeToGMT(format(now,DatePattern.yyyyMMdd)+ " 23:59:59");
        } catch (Exception e) {
            e.printStackTrace();
            return "";
        }
    }

//    /**
//     * 获得本小时的开始时间，即2012-01-01 23:59:59
//     *
//     * @return
//     */
//    public static Date getCurrentHourStartTime() {
//        Date now = DateUtil.getCurrentDate();
//        try {
//            now = longHourSdf.parse(longHourSdf.format(now));
//        } catch (Exception e) {
//            e.printStackTrace();
//        }
//        return now;
//    }
//
//    /**
//     * 获得本小时的结束时间，即2012-01-01 23:59:59
//     *
//     * @return
//     */
//    public static Date getCurrentHourEndTime() {
//        Date now = DateUtil.getCurrentDate();
//        try {
//            now = longSdf.parse(longHourSdf.format(now) + ":59:59");
//        } catch (Exception e) {
//            e.printStackTrace();
//        }
//        return now;
//    }

    /**
     * 获得本月的开始时间，即2012-01-01 00:00:00
     *
     * @return
     */
    public static String  getCurrentMonthStartTime() {
        Calendar c = Calendar.getInstance();
        Date now = null;
        try {
            c.set(Calendar.DATE, 1);
            now = shortSdf.parse(shortSdf.format(c.getTime()));
            return transferDatetimeToGMT(format(now,DatePattern.yyyyMMdd)+ " 00:00:00");
        } catch (Exception e) {
            e.printStackTrace();
            return "";
        }

    }

    /**
     * 当前月的结束时间，即2012-01-31 23:59:59
     *
     * @return
     */
    public static String getCurrentMonthEndTime() {
        Calendar c = Calendar.getInstance();
        Date now = null;
        try {
            c.set(Calendar.DATE, 1);
            c.add(Calendar.MONTH, 1);
            c.add(Calendar.DATE, -1);
            now = longSdf.parse(shortSdf.format(c.getTime()) + " 23:59:59");
            return transferDatetimeToGMT(format(now,DatePattern.yyyyMMdd)+ " 00:00:00");
        } catch (Exception e) {
            e.printStackTrace();
            return  "";
        }
    }

    /**
     * 当前年的开始时间，即2012-01-01 00:00:00
     *
     * @return
     */
    public static String getCurrentYearStartTime() {
        Calendar c = Calendar.getInstance();
        Date now = null;
        try {
            c.set(Calendar.MONTH, 0);
            c.set(Calendar.DATE, 1);
            now = shortSdf.parse(shortSdf.format(c.getTime()));
            return transferDatetimeToGMT(format(now,DatePattern.yyyyMMdd)+ " 00:00:00");
        } catch (Exception e) {
            e.printStackTrace();
            return "";
        }
    }

    /**
     * 当前年的结束时间，即2012-12-31 23:59:59
     *
     * @return
     */
    public static String getCurrentYearEndTime() {
        Calendar c = Calendar.getInstance();
        Date now = null;
        try {
            c.set(Calendar.MONTH, 11);
            c.set(Calendar.DATE, 31);
            now = longSdf.parse(shortSdf.format(c.getTime()) + " 23:59:59");
            return transferDatetimeToGMT(format(now,DatePattern.yyyyMMdd)+ " 00:00:00");
        } catch (Exception e) {
            e.printStackTrace();
            return "";
        }
    }

    /**
     * 当前季度的开始时间，即2012-01-1 00:00:00
     *
     * @return
     */
    public static String getCurrentQuarterStartTime() {
        Calendar c = Calendar.getInstance();
        int currentMonth = c.get(Calendar.MONTH) + 1;
        Date now = null;
        try {
            if (currentMonth >= 1 && currentMonth <= 3)
                c.set(Calendar.MONTH, 0);
            else if (currentMonth >= 4 && currentMonth <= 6)
                c.set(Calendar.MONTH, 3);
            else if (currentMonth >= 7 && currentMonth <= 9)
                c.set(Calendar.MONTH, 4);
            else if (currentMonth >= 10 && currentMonth <= 12)
                c.set(Calendar.MONTH, 9);
            c.set(Calendar.DATE, 1);
            now = longSdf.parse(shortSdf.format(c.getTime()) + " 00:00:00");
            return transferDatetimeToGMT(format(now,DatePattern.yyyyMMdd)+ " 00:00:00");
        } catch (Exception e) {
            e.printStackTrace();
            return "";
        }
    }

    /**
     * 当前季度的结束时间，即2012-03-31 23:59:59
     *
     * @return
     */
    public static String getCurrentQuarterEndTime() {
        Calendar c = Calendar.getInstance();
        int currentMonth = c.get(Calendar.MONTH) + 1;
        Date now = null;
        try {
            if (currentMonth >= 1 && currentMonth <= 3) {
                c.set(Calendar.MONTH, 2);
                c.set(Calendar.DATE, 31);
            } else if (currentMonth >= 4 && currentMonth <= 6) {
                c.set(Calendar.MONTH, 5);
                c.set(Calendar.DATE, 30);
            } else if (currentMonth >= 7 && currentMonth <= 9) {
                c.set(Calendar.MONTH, 8);
                c.set(Calendar.DATE, 30);
            } else if (currentMonth >= 10 && currentMonth <= 12) {
                c.set(Calendar.MONTH, 11);
                c.set(Calendar.DATE, 31);
            }
            now = longSdf.parse(shortSdf.format(c.getTime()) + " 23:59:59");
            return transferDatetimeToGMT(format(now,DatePattern.yyyyMMdd)+ " 00:00:00");
        } catch (Exception e) {
            e.printStackTrace();
            return "";
        }
    }

    /**
     * 获取前/后半年的开始时间
     *
     * @return
     */
    public static Date getHalfYearStartTime() {
        Calendar c = Calendar.getInstance();
        int currentMonth = c.get(Calendar.MONTH) + 1;
        Date now = null;
        try {
            if (currentMonth >= 1 && currentMonth <= 6) {
                c.set(Calendar.MONTH, 0);
            } else if (currentMonth >= 7 && currentMonth <= 12) {
                c.set(Calendar.MONTH, 6);
            }
            c.set(Calendar.DATE, 1);
            now = longSdf.parse(shortSdf.format(c.getTime()) + " 00:00:00");
        } catch (Exception e) {
            e.printStackTrace();
        }
        return now;

    }

    /**
     * 获取前/后半年的结束时间
     *
     * @return
     */
    public static Date getHalfYearEndTime() {
        Calendar c = Calendar.getInstance();
        int currentMonth = c.get(Calendar.MONTH) + 1;
        Date now = null;
        try {
            if (currentMonth >= 1 && currentMonth <= 6) {
                c.set(Calendar.MONTH, 5);
                c.set(Calendar.DATE, 30);
            } else if (currentMonth >= 7 && currentMonth <= 12) {
                c.set(Calendar.MONTH, 11);
                c.set(Calendar.DATE, 31);
            }
            now = longSdf.parse(shortSdf.format(c.getTime()) + " 23:59:59");
        } catch (Exception e) {
            e.printStackTrace();
        }
        return now;
    }

    public enum DatePattern {
        yyyyMMddHHmmss("yyyyMMddHHmmss"), ymr("yyyy年MM月dd日"), yyyyMMddHHmmssLine("yyyy-MM-dd HH:mm:ss"), yyyyMMdd(
                "yyyy-MM-dd"), ymrSlash("yyyy/MM/dd"), yyyyMMddHHmmssSlash("yyyy/MM/dd HH:mm:ss");
        private final String value;

        DatePattern(String value) {
            this.value = value;
        }

        public String getValue() {
            return this.value;
        }
    }

    /**
     * 日期转毫
     *
     * @param formatDate
     *            格式比如:yyyy-MM-dd
     * @param date
     * @return long 毫秒
     */
    public static final long stringDate2Long(String formatDate, String date) {
        return string2Date(formatDate, date).getTime();
    }

    /**
     * 将字符串表示的时间，转换成timestamp对象
     * @param formatDate 时间格式
     * @param strDate 字符串表示的时间，该时间的格式必须与formatDate一致
     * @return 转换好的时间戳对象
     */
    public static final Timestamp stringDate2Timestamp(String formatDate, String strDate){
        Date date = string2Date(formatDate, strDate);
        return new Timestamp(date.getTime());
    }

    /**
     * 日期转毫秒
     *
     * @param formatDate
     *            格式比如:yyyy-MM-dd
     * @param date 需要转换的时间
     * @return Date 日期对象
     */
    public static final Date string2Date(String formatDate, String date) {
        SimpleDateFormat sdf = new SimpleDateFormat(formatDate);
        sdf.setTimeZone(TimeZoneUtil.getDefaultTimeZone());
        try {
            return sdf.parse(date);
        } catch (ParseException e) {
            throw new RuntimeException(e);
        }
    }

    public static final String date2String(Date date,String format){
        return date2String(date,format,TimeZoneUtil.getDefaultTimeZone());
    }
    /**
     * 将时间格式化为字符串
     * @param date 被格式化的时间对象
     * @param format 标准的JDK提供的格式
     * @param timeZone 时区  ，根据不同的时区，转换成不同时区的时间
     * @return 格式后的字符串
     */
    public static final String date2String(Date date,String format,TimeZone timeZone){
        SimpleDateFormat sdf = new SimpleDateFormat(format);
        sdf.setTimeZone(timeZone);
        return sdf.format(date);
    }
}
